﻿using System;
using System.Collections;
using System.Configuration;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace Ellanet
{
    public partial class vmrunGUI : Form // KryptonForm
    {
        const string vmrunGUIXmlName = "vmrunGUI.xml";
        const string dateToStringFormat = "HH:mm:ss";
        const int guestOnImageIndex = 0;
        const int guestOffImageIndex = 1;
        const int guestSuspendedImageIndex = 2;
        const int guestWarningIconIndex = 3;

        //string vmrunGUIXmlDirectory = Environment.ExpandEnvironmentVariables(@"%APPDATA%\Ellanet\vmrunGUI");
        int vmrunProcessTimeoutSeconds = 60;
        int guestStateUpdateIntervalSeconds = 60;
        ImageList guestStateImages = new ImageList();
        string vmrunGUIXmlPath = null;
        //string vmrunDefaultPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"VMware\VMware VIX\vmrun.exe");
        ToolTip tt = null;
        ContextMenu rightClickMenu;
        Color outputNormalColour = Color.Blue;
        Color outputSuccessColour = Color.Green;
        Color outputFailureColour = Color.Red;
        Thread executeCommandThread;
        Thread updateGuestStatusThread;
        string lastCategory = null;
        string lastCommand = null;
        ConsoleOutputType outputType = ConsoleOutputType.RichTextFile;
        DateTime nextUpdateGuestStatusTime = new DateTime(1980, 3, 31, 0, 0, 0);
        ListViewColumnSorter guestColumnSorter;
        ListViewColumnSorter managedGuestColumnSorter;
        ListViewColumnSorter managedHostColumnSorter;
        ListViewColumnSorter managedCredentialsColumnSorter;

        delegate void WriteToRichTextBoxDelegate(ref RichTextBox rtb, string text, Color colour, bool bold);
        delegate string GetComboBoxTextPropertyDelegate(ref ComboBox cb);
        delegate int GetComboBoxSelectedIndexDelegate(ref ComboBox cb);
        delegate vmrunGUIXmlWrapper.VMwareGuest[] GetSelectedGuestsDelegate(ref ListView lv);
        delegate vmrunGUIXmlWrapper.VMwareGuest[] GetGuestsDelegate(ref ListView lv);
        delegate string GetTextBoxTextPropertyDelegate(ref TextBox tb);
        delegate void SetButtonEnablePropertyDelegate(ref Button b, bool enabled);
        delegate void SetTabPageEnableStateDelegate(ref TabPage tp, bool enabled);
        delegate void SetTabControlSelectedIndexDelegate(ref TabControl tc, int index);
        delegate void UpdateGuestStateImagesDelegate(vmrunGUIXmlWrapper.VMwareGuest[] poweredOnGuests);

        enum ConsoleOutputType
        {
            Script,
            RichTextFile
        }

        public vmrunGUI()
        {
            InitializeComponent();
            managedHostListView.Height = 187;
            managedGuestListView.Height = 187;
            managedCredentialsListView.Height = 187;
            guestColumnSorter = new ListViewColumnSorter();
            guestListView.ListViewItemSorter = guestColumnSorter;
            managedGuestColumnSorter = new ListViewColumnSorter();
            managedGuestListView.ListViewItemSorter = managedGuestColumnSorter;
            managedHostColumnSorter = new ListViewColumnSorter();
            managedHostListView.ListViewItemSorter = managedHostColumnSorter;
            managedCredentialsColumnSorter = new ListViewColumnSorter();
            managedCredentialsListView.ListViewItemSorter = managedCredentialsColumnSorter;
            guestStateImages.Images.Add(new Bitmap(global::Ellanet.Properties.Resources.vm_power_on_Image));
            guestStateImages.Images.Add(new Bitmap(global::Ellanet.Properties.Resources.vm_power_off_Image));
            guestStateImages.Images.Add(new Bitmap(global::Ellanet.Properties.Resources.vm_suspended_Image));
            guestStateImages.Images.Add(new Bitmap(global::Ellanet.Properties.Resources.Help_Image));
            guestListView.SmallImageList = guestStateImages;
            this.Text = String.Format("vmrunGUI ({0}.{1}.{2}) - http://vmrungui.codeplex.com/", Assembly.GetExecutingAssembly().GetName().Version.Major, Assembly.GetExecutingAssembly().GetName().Version.Minor, Assembly.GetExecutingAssembly().GetName().Version.Build);
            this.Load += new EventHandler(vmrunGUI_Load);
            closeButton.Click += new EventHandler(closeButton_Click);
            vmrunBrowseButton.Click += new EventHandler(vmrunBrowseButton_Click);
            addHostButton.Click += new EventHandler(addHostButton_Click);
            editHostButton.Click += new EventHandler(editHostButton_Click);
            removeHostButton.Click += new EventHandler(removeHostButton_Click);
            addGuestButton.Click += new EventHandler(addGuestButton_Click);
            editGuestButton.Click += new EventHandler(editGuestButton_Click);
            removeGuestButton.Click += new EventHandler(removeGuestButton_Click);
            addCredentialsButton.Click += new EventHandler(addCredentialsButton_Click);
            editCredentialsButton.Click += new EventHandler(editCredentialsButton_Click);
            removeCredentialsButton.Click += new EventHandler(removeCredentialsButton_Click);
            managedGuestListView.SelectedIndexChanged += new EventHandler(managedGuestsListView_SelectedIndexChanged);
            managedHostListView.SelectedIndexChanged += new EventHandler(managedHostsListView_SelectedIndexChanged);
            managedGuestListView.DoubleClick += new EventHandler(managedGuestsListView_DoubleClick);
            managedHostListView.DoubleClick += new EventHandler(managedHostsListView_DoubleClick);
            managedCredentialsListView.SelectedIndexChanged += new EventHandler(managedCredentialsListView_SelectedIndexChanged);
            managedCredentialsListView.DoubleClick += new EventHandler(managedCredentialsListView_DoubleClick);
            selectAllButton.Click += new EventHandler(selectAllButton_Click);
            categoryComboBox.SelectedIndexChanged += new EventHandler(categoryComboBox_SelectedIndexChanged);
            commandComboBox.SelectedIndexChanged += new EventHandler(commandComboBox_SelectedIndexChanged);
            guestListView.ItemChecked += new ItemCheckedEventHandler(guestListView_ItemChecked);
            commandComboBox.MouseHover += new EventHandler(commandComboBox_MouseHover);
            executeButton.Click += new EventHandler(executeButton_Click);
            simulateButton.Click += new EventHandler(simulateButton_Click);
            managedHostListView.MouseClick += new MouseEventHandler(managedHostListView_MouseClick);
            managedGuestListView.MouseClick += new MouseEventHandler(managedGuestListView_MouseClick);
            managedCredentialsListView.MouseClick += new MouseEventHandler(managedCredentialsListView_MouseClick);
            abortButton.Click += new EventHandler(abortButton_Click);
            this.FormClosing += new FormClosingEventHandler(vmrunGUI_FormClosing);
            clearConsoleButton.Click += new EventHandler(clearConsoleButton_Click);
            saveConsoleButton.Click += new EventHandler(saveConsoleButton_Click);
            guestListView.MouseClick += new MouseEventHandler(guestListView_MouseClick);
            guestListView.ColumnClick += new ColumnClickEventHandler(guestListView_ColumnClick);
            managedGuestListView.ColumnClick += new ColumnClickEventHandler(managedGuestListView_ColumnClick);
            managedHostListView.ColumnClick += new ColumnClickEventHandler(managedHostListView_ColumnClick);
            managedCredentialsListView.ColumnClick += new ColumnClickEventHandler(managedCredentialsListView_ColumnClick);
            vmrunPathTextBox.TextChanged += new EventHandler(vmrunPathTextBox_TextChanged);
        }

        void vmrunPathTextBox_TextChanged(object sender, EventArgs e)
        {
            if (vmrunPathTextBox.Text != null)
            {
                vixInfoWrapper vixInfoWrapper = new vixInfoWrapper();
                vixInfoWrapper.CheckLatestVIXAPIInstalled(vmrunPathTextBox.Text);
                vixInfoWrapper.ImplementationDirectoriesExist(new FileInfo(vmrunPathTextBox.Text).DirectoryName, true);
            }
        }

        void managedCredentialsListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (e.Column == managedCredentialsColumnSorter.SortColumn)
            {
                if (managedCredentialsColumnSorter.Order == SortOrder.Ascending)
                {
                    managedCredentialsColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    managedCredentialsColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                managedCredentialsColumnSorter.SortColumn = e.Column;
                managedCredentialsColumnSorter.Order = SortOrder.Ascending;
            }

            managedCredentialsListView.Sort();
        }

        void managedHostListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (e.Column == managedHostColumnSorter.SortColumn)
            {
                if (managedHostColumnSorter.Order == SortOrder.Ascending)
                {
                    managedHostColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    managedHostColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                managedHostColumnSorter.SortColumn = e.Column;
                managedHostColumnSorter.Order = SortOrder.Ascending;
            }

            managedHostListView.Sort();
        }

        void managedGuestListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (e.Column == managedGuestColumnSorter.SortColumn)
            {
                if (managedGuestColumnSorter.Order == SortOrder.Ascending)
                {
                    managedGuestColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    managedGuestColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                managedGuestColumnSorter.SortColumn = e.Column;
                managedGuestColumnSorter.Order = SortOrder.Ascending;
            }

            managedGuestListView.Sort();
        }

        void guestListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (e.Column == guestColumnSorter.SortColumn)
            {
                if (guestColumnSorter.Order == SortOrder.Ascending)
                {
                    guestColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    guestColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                guestColumnSorter.SortColumn = e.Column;
                guestColumnSorter.Order = SortOrder.Ascending;
            }

            guestListView.Sort();
        }

        void guestListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (rightClickMenu != null)
                {
                    rightClickMenu.Dispose();
                }

                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                string selectedGuestName = guestListView.SelectedItems[0].SubItems[0].Text;
                string selectedGuestVMX = guestListView.SelectedItems[0].Tag.ToString();
                string selectedGuestHost = guestListView.SelectedItems[0].SubItems[2].Text;
                XmlDocument tagXmlDoc = new XmlDocument();
                tagXmlDoc.LoadXml("<tag><host /><vmx_path /></tag>");
                tagXmlDoc.SelectSingleNode("tag/host").InnerText = selectedGuestHost;
                tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText = selectedGuestVMX;
                rightClickMenu = new ContextMenu();
                MenuItem editGuestMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0}", selectedGuestName), EditGuestClick);
                editGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                MenuItem removeHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Remove {0}", selectedGuestName), RemoveGuestClick);
                removeHostMenuItem.Tag = tagXmlDoc.InnerXml;
                MenuItem editHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0} Host", selectedGuestHost), EditHostClick);
                editHostMenuItem.Tag = selectedGuestHost;  //MenuItem guestsMenuItem = rightClickMenu.MenuItems.Add("Guests");
                string credentials = guiXmlWrapper.GetGuestChildNodeInnerText(selectedGuestVMX, selectedGuestHost, "credentials");

                if ((credentials != null) && (credentials.Trim().Length > 0))
                {
                    MenuItem editCredentialsMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0} Credentials", credentials), EditCredentialsClick);
                    editCredentialsMenuItem.Tag = credentials;
                }

                rightClickMenu.Show(guestListView, e.Location);
            }
            //else
            //{
            //    if (guestListView.SelectedItems.Count > 0)
            //    {
            //        guestListView.SelectedItems[0].Checked = (!guestListView.SelectedItems[0].Checked);
            //    }
            //}

            //if (guestListView.SelectedItems.Count > 0)
            //{
            //    guestListView.SelectedItems[0].Selected = false;
            //}
        }

        void managedCredentialsListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (rightClickMenu != null)
                {
                    rightClickMenu.Dispose();
                }

                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                string selectedCredentials = managedCredentialsListView.SelectedItems[0].SubItems[0].Text;
                rightClickMenu = new ContextMenu();
                MenuItem editCredentialsMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0}", selectedCredentials), EditCredentialsClick);
                editCredentialsMenuItem.Tag = selectedCredentials;
                MenuItem removeCredentialsMenuItem = rightClickMenu.MenuItems.Add(String.Format("Remove {0}", selectedCredentials), RemoveCredentialsClick);
                removeCredentialsMenuItem.Tag = selectedCredentials;

                if (guiXmlWrapper.GetHostsByCredentials(selectedCredentials).Count > 0)
                {
                    MenuItem hostsMenuItem = rightClickMenu.MenuItems.Add("Hosts");

                    foreach (string host in guiXmlWrapper.GetHostsByCredentials(selectedCredentials))
                    {
                        MenuItem hostMenuItem = hostsMenuItem.MenuItems.Add(String.Format("{0}", host));
                        MenuItem editHostMenuItem = hostMenuItem.MenuItems.Add("Edit", EditHostClick);
                        editHostMenuItem.Tag = host;
                        MenuItem removeHostMenuItem = hostMenuItem.MenuItems.Add("Remove", RemoveHostClick);
                        removeHostMenuItem.Tag = host;
                    }
                }

                if (guiXmlWrapper.GetGuestsByCredentials(selectedCredentials).Length > 0)
                {
                    MenuItem guestsMenuItem = rightClickMenu.MenuItems.Add("Guests");

                    foreach (vmrunGUIXmlWrapper.VMwareGuest guest in guiXmlWrapper.GetGuestsByCredentials(selectedCredentials))
                    {
                        XmlDocument tagXmlDoc = new XmlDocument();
                        tagXmlDoc.LoadXml("<tag><host /><vmx_path /></tag>");
                        tagXmlDoc.SelectSingleNode("tag/host").InnerText = guest.host;
                        tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText = guest.vmxPath;
                        MenuItem guestMenuItem = guestsMenuItem.MenuItems.Add(String.Format("{0}", guiXmlWrapper.GetGuestChildNodeInnerText(guest.vmxPath, guest.host, "name")));
                        MenuItem editGuestMenuItem = guestMenuItem.MenuItems.Add("Edit", EditGuestClick);
                        editGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                        MenuItem removeGuestMenuItem = guestMenuItem.MenuItems.Add("Remove", RemoveGuestClick);
                        removeGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                    }
                }

                rightClickMenu.Show(managedCredentialsListView, e.Location);
            }
        }

        void managedGuestListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (rightClickMenu != null)
                {
                    rightClickMenu.Dispose();
                }

                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                string selectedGuestName = managedGuestListView.SelectedItems[0].SubItems[0].Text;
                string selectedGuestVMX = managedGuestListView.SelectedItems[0].Tag.ToString();
                string selectedGuestHost = managedGuestListView.SelectedItems[0].SubItems[1].Text;
                XmlDocument tagXmlDoc = new XmlDocument();
                tagXmlDoc.LoadXml("<tag><host /><vmx_path /></tag>");
                tagXmlDoc.SelectSingleNode("tag/host").InnerText = selectedGuestHost;
                tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText = selectedGuestVMX;
                rightClickMenu = new ContextMenu();
                MenuItem editGuestMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0}", selectedGuestName), EditGuestClick);
                editGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                MenuItem removeHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Remove {0}", selectedGuestName), RemoveGuestClick);
                removeHostMenuItem.Tag = tagXmlDoc.InnerXml;
                MenuItem editHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0} Host", selectedGuestHost), EditHostClick);
                editHostMenuItem.Tag = selectedGuestHost;  //MenuItem guestsMenuItem = rightClickMenu.MenuItems.Add("Guests");
                string credentials = guiXmlWrapper.GetGuestChildNodeInnerText(selectedGuestVMX, selectedGuestHost, "credentials");

                if ((credentials != null) && (credentials.Trim().Length > 0))
                {
                    MenuItem editCredentialsMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0} Credentials", credentials), EditCredentialsClick);
                    editCredentialsMenuItem.Tag = credentials;
                }

                rightClickMenu.Show(managedGuestListView, e.Location);
            }
        }

        void saveConsoleButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.AddExtension = true;
            sfd.OverwritePrompt = true;
            sfd.ValidateNames = true;

            switch (outputType)
            {
                case ConsoleOutputType.RichTextFile:
                    sfd.DefaultExt = "rtf";
                    sfd.Filter = "Rich Text File (*.rtf)|*.rtf";
                    break;
                case ConsoleOutputType.Script:
                    sfd.DefaultExt = "cmd";
                    sfd.Filter = "Windows Command Script (*.cmd)|*.cmd";
                    break;
            }

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                switch (outputType)
                {
                    case ConsoleOutputType.RichTextFile:
                        consoleRichTextBox.SaveFile(sfd.FileName);
                        break;
                    case ConsoleOutputType.Script:
                        StreamWriter sw = new StreamWriter(sfd.FileName, false);

                        foreach (string line in consoleRichTextBox.Text.Split(Convert.ToChar("\n")))
                        {
                            sw.WriteLine(String.Format("{0}", line));
                        }

                        sw.Close();
                        break;
                }
            }
        }

        void clearConsoleButton_Click(object sender, EventArgs e)
        {
            consoleRichTextBox.Clear();
        }

        void vmrunGUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            updateGuestStatusThread.Abort();

            if (abortButton.Enabled)
            {
                abortButton.PerformClick();
            }
        }

        void abortButton_Click(object sender, EventArgs e)
        {
            executeCommandThread.Abort();
            nextUpdateGuestStatusTime = DateTime.Now;
            SetButtonEnableProperty(ref abortButton, false);
            SetButtonEnableProperty(ref saveConsoleButton, true);
            SetButtonEnableProperty(ref clearConsoleButton, true);
            SetTabPageEnableState(ref guestTabPage, true);
            SetTabPageEnableState(ref optionsTabPage, true);
            WriteToRichTextBox(ref consoleRichTextBox, "vmrunGUI aborted.", outputFailureColour, true);
        }

        void managedHostListView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (rightClickMenu != null)
                {
                    rightClickMenu.Dispose();
                }

                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                string selectedHost = managedHostListView.SelectedItems[0].SubItems[0].Text;
                rightClickMenu = new ContextMenu();
                MenuItem editHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0}", selectedHost), EditHostClick);
                editHostMenuItem.Tag = selectedHost;
                MenuItem removeHostMenuItem = rightClickMenu.MenuItems.Add(String.Format("Remove {0}", selectedHost), RemoveHostClick);
                removeHostMenuItem.Tag = selectedHost;
                MenuItem guestsMenuItem = rightClickMenu.MenuItems.Add("Guests");
                MenuItem addGuestMenuItem = guestsMenuItem.MenuItems.Add("Add Guest", AddGuestClick);
                addGuestMenuItem.Tag = selectedHost;

                if (guiXmlWrapper.GetGuestsFromHost(selectedHost).Count > 0)
                {
                    guestsMenuItem.MenuItems.Add("-");

                    foreach (string guest in guiXmlWrapper.GetGuestsFromHost(selectedHost))
                    {
                        XmlDocument tagXmlDoc = new XmlDocument();
                        tagXmlDoc.LoadXml("<tag><host /><vmx_path /></tag>");
                        tagXmlDoc.SelectSingleNode("tag/host").InnerText = selectedHost;
                        tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText = guest;
                        MenuItem guestMenuItem = guestsMenuItem.MenuItems.Add(String.Format("{0}", guiXmlWrapper.GetGuestChildNodeInnerText(guest, selectedHost, "name")));
                        MenuItem editGuestMenuItem = guestMenuItem.MenuItems.Add("Edit", EditGuestClick);
                        editGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                        MenuItem removeGuestMenuItem = guestMenuItem.MenuItems.Add("Remove", RemoveGuestClick);
                        removeGuestMenuItem.Tag = tagXmlDoc.InnerXml;
                    }
                }

                string credentials = guiXmlWrapper.GetHostChildNodeInnerText(selectedHost, "credentials");

                if ((credentials != null) && (credentials.Trim().Length > 0))
                {
                    MenuItem editCredentialsMenuItem = rightClickMenu.MenuItems.Add(String.Format("Edit {0} Credentials", credentials), EditCredentialsClick);
                    editCredentialsMenuItem.Tag = credentials;
                }

                rightClickMenu.Show(managedHostListView, e.Location);
            }
        }

        private void EditHostClick(object sender, EventArgs e)
        {
            EditHost(((MenuItem)sender).Tag.ToString());
        }

        private void RemoveHostClick(object sender, EventArgs e)
        {
            RemoveHost(((MenuItem)sender).Tag.ToString());
        }

        private void AddGuestClick(object sender, EventArgs e)
        {
            AddGuest(((MenuItem)sender).Tag.ToString());
        }

        private void EditGuestClick(object sender, EventArgs e)
        {
            XmlDocument tagXmlDoc = new XmlDocument();
            tagXmlDoc.LoadXml(((MenuItem)sender).Tag.ToString());
            EditGuest(tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText, tagXmlDoc.SelectSingleNode("tag/host").InnerText);
        }

        private void RemoveGuestClick(object sender, EventArgs e)
        {
            XmlDocument tagXmlDoc = new XmlDocument();
            tagXmlDoc.LoadXml(((MenuItem)sender).Tag.ToString());
            RemoveGuest(tagXmlDoc.SelectSingleNode("tag/vmx_path").InnerText, tagXmlDoc.SelectSingleNode("tag/host").InnerText);
        }

        private void EditCredentialsClick(object sender, EventArgs e)
        {
            EditCredentials(((MenuItem)sender).Tag.ToString());
        }

        private void RemoveCredentialsClick(object sender, EventArgs e)
        {
            RemoveCredentials(((MenuItem)sender).Tag.ToString());
        }

        void removeCredentialsButton_Click(object sender, EventArgs e)
        {
            RemoveCredentials(managedCredentialsListView.SelectedItems[0].SubItems[0].Text);
        }

        void editCredentialsButton_Click(object sender, EventArgs e)
        {
            EditCredentials(managedCredentialsListView.SelectedItems[0].SubItems[0].Text);
        }

        void addCredentialsButton_Click(object sender, EventArgs e)
        {
            AddCredentials();
        }

        void EditCredentials(string credentials)
        {
            Credentials cred = new Credentials(credentials, vmrunGUIXmlPath);

            if (cred.ShowDialog() == DialogResult.OK)
            {
                UpdateUI();
            }
        }

        void RemoveCredentials(string credentials)
        {
            vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);

            if (!guiXmlWrapper.CredentialsInUse(credentials))
            {
                guiXmlWrapper.RemoveCredentials(credentials);
                guiXmlWrapper.SaveXml();
                UpdateUI();
            }
            else
            {
                MessageBox.Show("You can not remove Credentials that are being used by Hosts or Guests.\r\rPlease ensure no Hosts or Guests are using these Credentials before attempting to remove them.", "Credentials In Use", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        void AddCredentials()
        {
            Credentials cred = new Credentials(null, vmrunGUIXmlPath);

            if (cred.ShowDialog() == DialogResult.OK)
            {
                UpdateUI();
            }
        }

        void managedCredentialsListView_DoubleClick(object sender, EventArgs e)
        {
            EditCredentials(managedCredentialsListView.SelectedItems[0].SubItems[0].Text);
        }

        void managedCredentialsListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (managedCredentialsListView.SelectedIndices.Count > 0)
            {
                editCredentialsButton.Enabled = true;
                removeCredentialsButton.Enabled = true;
            }
            else
            {
                editCredentialsButton.Enabled = false;
                removeCredentialsButton.Enabled = false;
            }
        }

        void simulateButton_Click(object sender, EventArgs e)
        {
            if ((executeCommandThread == null) || (executeCommandThread.ThreadState == System.Threading.ThreadState.Stopped))
            {
                consoleRichTextBox.Clear();
                executeCommandThread = new Thread(new ParameterizedThreadStart(ExecuteCommand));
                executeCommandThread.Start(true);
            }
        }

        void executeButton_Click(object sender, EventArgs e)
        {
            if ((executeCommandThread == null) || (executeCommandThread.ThreadState == System.Threading.ThreadState.Stopped))
            {
                executeCommandThread = new Thread(new ParameterizedThreadStart(ExecuteCommand));
                executeCommandThread.Start(false);
            }
        }

        void ExecuteCommand(object simulate)
        {
            try
            {
                if (GetComboBoxSelectedIndex(ref commandComboBox) > -1)
                {
                    vmrunInfoXmlWrapper infoXmlWrapper = new vmrunInfoXmlWrapper();
                    vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                    string parameterArgs = String.Empty;
                    ArrayList simulatedVariables = new ArrayList();
                    ArrayList simulatedCommands = new ArrayList();

                    if (infoXmlWrapper.CommandHasParameters(GetComboBoxTextProperty(ref commandComboBox)))
                    {
                        DynamicParameters dp = new DynamicParameters(GetComboBoxTextProperty(ref commandComboBox));

                        foreach (vmrunInfoXmlWrapper.CommandParameter parameter in infoXmlWrapper.GetCommandParameters(GetComboBoxTextProperty(ref commandComboBox)))
                        {
                            switch (parameter.type)
                            {
                                case vmrunInfoXmlWrapper.CommandParameterType.list:
                                    dp.AddListParameter(parameter.name, parameter.items, parameter.hint);
                                    break;
                                case vmrunInfoXmlWrapper.CommandParameterType.boolean:
                                    dp.AddBooleanParameter(parameter.name, parameter.hint);
                                    break;
                                case vmrunInfoXmlWrapper.CommandParameterType.text:
                                    dp.AddTextParameter(parameter.name, parameter.hint);
                                    break;
                            }
                        }

                        if (dp.ShowDialog() == DialogResult.OK)
                        {
                            parameterArgs = String.Format(" {0}", dp.ArgumentString);
                        }
                        else
                        {
                            return;
                        }
                    }

                    SetTabControlSelectedIndex(ref mainTabControl, 1);
                    SetButtonEnableProperty(ref abortButton, true);
                    SetButtonEnableProperty(ref saveConsoleButton, false);
                    SetButtonEnableProperty(ref clearConsoleButton, false);
                    SetTabPageEnableState(ref guestTabPage, false);
                    SetTabPageEnableState(ref optionsTabPage, false);

                    if (!Convert.ToBoolean(simulate))
                    {
                        WriteToRichTextBox(ref consoleRichTextBox, String.Format("vmrunGUI starting ({0}).", DateTime.Now.ToString(dateToStringFormat)), outputNormalColour, true);
                        outputType = ConsoleOutputType.RichTextFile;
                    }
                    else
                    {
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO OFF", outputNormalColour, false);
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO               ###################################################", outputNormalColour, false);
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO               #      This script was generated by vmrunGUI      #", outputNormalColour, false);
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO               #                                                 #", outputNormalColour, false);
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO               #          http://vmrungui.codeplex.com/          #", outputNormalColour, false);
                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO               ###################################################\r", outputNormalColour, false);
                        outputType = ConsoleOutputType.Script;
                    }

                    foreach (vmrunGUIXmlWrapper.VMwareGuest guest in GetSelectedGuests(ref guestListView))
                    {
                        string vmrunArgs = null;
                        string vmxPath = String.Empty;
                        string hostUsername = null;
                        string hostPassword = null;
                        string guestUsername = null;
                        string guestPassword = null;
                        guiXmlWrapper.GetCredentials(guiXmlWrapper.GetHostChildNodeInnerText(guest.host, "credentials"), out hostUsername, out hostPassword);

                        if (infoXmlWrapper.CommandRequiresGuestLogin(GetComboBoxTextProperty(ref commandComboBox)))
                        {
                            guiXmlWrapper.GetCredentials(guiXmlWrapper.GetGuestChildNodeInnerText(guest.vmxPath, guest.host, "credentials"), out guestUsername, out guestPassword);
                        }

                        if (infoXmlWrapper.CommandRequiresVMXPath(GetComboBoxTextProperty(ref commandComboBox)))
                        {
                            vmxPath = String.Format(" \"{0}\"", guest.vmxPath);
                        }

                        vmrunArgs += String.Format("{0}{1}{2}", GetComboBoxTextProperty(ref commandComboBox), vmxPath, parameterArgs);
                        vmrunCLIWrapper cliWrapper = new vmrunCLIWrapper(vmrunPathTextBox.Text, guiXmlWrapper.GetHostType(guest.host), guiXmlWrapper.GetHostChildNodeInnerText(guest.host, "arguments"), hostUsername, hostPassword, guestUsername, guestPassword, vmrunArgs);

                        if (Convert.ToBoolean(simulate))
                        {
                            string command = String.Format("{0} {1}", "%VMRUN_PATH%", cliWrapper.PasswordSafeArguments);

                            if (hostUsername != null)
                            {
                                string hostCredentials = ConvertToBatchPasswordVariable(guiXmlWrapper.GetHostChildNodeInnerText(guest.host, "credentials"));
                                command = command.Replace("%HOST_PASSWORD%", String.Format("%{0}%", hostCredentials));

                                if (!simulatedVariables.Contains(hostCredentials))
                                {
                                    simulatedVariables.Add(hostCredentials);
                                }
                            }

                            if (infoXmlWrapper.CommandRequiresGuestLogin(GetComboBoxTextProperty(ref commandComboBox)))
                            {
                                string guestCredentials = ConvertToBatchPasswordVariable(guiXmlWrapper.GetGuestChildNodeInnerText(guest.vmxPath, guest.host, "credentials"));
                                command = command.Replace("%GUEST_PASSWORD%", String.Format("%{0}%", guestCredentials));

                                if (!simulatedVariables.Contains(guestCredentials))
                                {
                                    simulatedVariables.Add(guestCredentials);
                                }
                            }

                            simulatedCommands.Add(command);
                        }
                        else
                        {
                            outputType = ConsoleOutputType.RichTextFile;
                            WriteToRichTextBox(ref consoleRichTextBox, String.Format("\"{0}\" {1}", GetTextBoxTextProperty(ref vmrunPathTextBox), cliWrapper.PasswordSafeArguments), outputNormalColour, false);
                            ArrayList vmrunOut;
                            int exitCode;
                            cliWrapper.ExecuteCommand(vmrunProcessTimeoutSeconds, out vmrunOut, out exitCode);

                            foreach (string line in vmrunOut)
                            {
                                if (exitCode == 0)
                                {
                                    WriteToRichTextBox(ref consoleRichTextBox, line, outputSuccessColour, false);
                                }
                                else
                                {
                                    WriteToRichTextBox(ref consoleRichTextBox, line, outputFailureColour, false);
                                }
                            }
                        }
                    }

                    nextUpdateGuestStatusTime = DateTime.Now;
                    SetButtonEnableProperty(ref abortButton, false);
                    SetButtonEnableProperty(ref saveConsoleButton, true);
                    SetButtonEnableProperty(ref clearConsoleButton, true);
                    SetTabPageEnableState(ref guestTabPage, true);
                    SetTabPageEnableState(ref optionsTabPage, true);

                    if (Convert.ToBoolean(simulate))
                    {
                        WriteToRichTextBox(ref consoleRichTextBox, String.Format("SET VMRUN_PATH=\"{0}\"", GetTextBoxTextProperty(ref vmrunPathTextBox)), outputNormalColour, false);

                        if (simulatedVariables.Count > 0)
                        {
                            WriteToRichTextBox(ref consoleRichTextBox, "REM Specify passwords here before executing the script.", outputNormalColour, false);

                            foreach (string variable in simulatedVariables)
                            {
                                WriteToRichTextBox(ref consoleRichTextBox, String.Format("SET {0}=?", variable), outputNormalColour, false);
                            }

                            WriteToRichTextBox(ref consoleRichTextBox, "", outputNormalColour, false);
                        }

                        WriteToRichTextBox(ref consoleRichTextBox, "@ECHO ON", outputNormalColour, false);

                        foreach (string command in simulatedCommands)
                        {
                            WriteToRichTextBox(ref consoleRichTextBox, command, outputNormalColour, false);
                        }

                        WriteToRichTextBox(ref consoleRichTextBox, "PAUSE", outputNormalColour, false);
                    }
                    else
                    {
                        WriteToRichTextBox(ref consoleRichTextBox, String.Format("vmrunGUI complete ({0}).", DateTime.Now.ToString(dateToStringFormat)), outputNormalColour, true);
                    }
                }
            }
            catch
            {
            }
        }

        void commandComboBox_MouseHover(object sender, EventArgs e)
        {
            if (commandComboBox.SelectedIndex > -1)
            {
                if (tt != null)
                {
                    tt.Dispose();
                }

                tt = new ToolTip();
                tt.RemoveAll();
                tt.ToolTipTitle = commandComboBox.Text;
                tt.ToolTipIcon = ToolTipIcon.Info;
                tt.UseAnimation = true;
                tt.UseFading = true;
                tt.SetToolTip(commandComboBox, new vmrunInfoXmlWrapper().GetCommandHint(commandComboBox.Text));
            }
        }

        void guestListView_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            categoryComboBox.Items.Clear();
            commandComboBox.Items.Clear();
            executeButton.Enabled = false;
            simulateButton.Enabled = false;

            if (guestListView.CheckedItems.Count > 0)
            {
                ListvmrunCommandCategories();
            }
        }

        void commandComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (commandComboBox.SelectedIndex > -1)
            {
                lastCommand = commandComboBox.Text;
                executeButton.Enabled = true;
                simulateButton.Enabled = true;
            }
        }

        void categoryComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            commandComboBox.Items.Clear();
            executeButton.Enabled = false;
            simulateButton.Enabled = false;

            if (tt != null)
            {
                tt.Dispose();
            }

            if (categoryComboBox.SelectedIndex > -1)
            {
                lastCategory = categoryComboBox.Text;
                ListvmrunCommands();
            }
        }

        void ListvmrunCommands()
        {
            foreach (string command in new vmrunInfoXmlWrapper().GetvmrunCommands(categoryComboBox.Text, GetSelectedGuestHostTypes()))
            {
                commandComboBox.Items.Add(command);
            }

            if (commandComboBox.Tag != null)
            {
                commandComboBox.Text = lastCommand;
            }
        }

        void ListvmrunCommandCategories()
        {
            foreach (string category in new vmrunInfoXmlWrapper().GetvmrunCommandCategories(GetSelectedGuestHostTypes()))
            {
                categoryComboBox.Items.Add(category);
            }

            if (categoryComboBox.Tag != null)
            {
                categoryComboBox.Text = lastCategory;
            }
        }

        ArrayList GetSelectedGuestHostTypes()
        {
            ArrayList hosts = new ArrayList();
            vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);

            if (guestListView.CheckedItems.Count > 0)
            {
                foreach (ListViewItem lvi in guestListView.CheckedItems)
                {
                    string host = guiXmlWrapper.GetHostType(lvi.SubItems[2].Text);

                    if (!hosts.Contains(host))
                    {
                        hosts.Add(host);
                    }
                }
            }

            return hosts;
        }

        void selectAllButton_Click(object sender, EventArgs e)
        {
            if (guestListView.Items.Count > 0)
            {
                bool selected = Convert.ToBoolean(guestListView.Items.Count != guestListView.CheckedItems.Count);

                for (int i = 0; i < guestListView.Items.Count; i++)
                {
                    guestListView.Items[i].Checked = selected;
                }
            }
        }

        void managedHostsListView_DoubleClick(object sender, EventArgs e)
        {
            EditHost(managedHostListView.SelectedItems[0].SubItems[0].Text);
        }

        void managedGuestsListView_DoubleClick(object sender, EventArgs e)
        {
            EditGuest(managedGuestListView.SelectedItems[0].Tag.ToString(), managedGuestListView.SelectedItems[0].SubItems[1].Text);
        }

        void managedHostsListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (managedHostListView.SelectedIndices.Count > 0)
            {
                editHostButton.Enabled = true;
                removeHostButton.Enabled = true;
            }
            else
            {
                editHostButton.Enabled = false;
                removeHostButton.Enabled = false;
            }
        }

        void managedGuestsListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (managedGuestListView.SelectedIndices.Count > 0)
            {
                editGuestButton.Enabled = true;
                removeGuestButton.Enabled = true;
            }
            else
            {
                editGuestButton.Enabled = false;
                removeGuestButton.Enabled = false;
            }
        }

        void removeGuestButton_Click(object sender, EventArgs e)
        {
            RemoveGuest(managedGuestListView.SelectedItems[0].Tag.ToString(), managedGuestListView.SelectedItems[0].SubItems[1].Text);
        }

        void editGuestButton_Click(object sender, EventArgs e)
        {
            EditGuest(managedGuestListView.SelectedItems[0].Tag.ToString(), managedGuestListView.SelectedItems[0].SubItems[1].Text);
        }

        void addGuestButton_Click(object sender, EventArgs e)
        {
            AddGuest(null);
        }

        void removeHostButton_Click(object sender, EventArgs e)
        {
            RemoveHost(managedHostListView.SelectedItems[0].SubItems[0].Text);
        }

        void editHostButton_Click(object sender, EventArgs e)
        {
            EditHost(managedHostListView.SelectedItems[0].SubItems[0].Text);
        }

        void addHostButton_Click(object sender, EventArgs e)
        {
            AddHost();
        }

        void EditHost(string hostName)
        {
            Host ah = new Host(hostName, vmrunGUIXmlPath, vmrunPathTextBox.Text);

            if (ah.ShowDialog() == DialogResult.OK)
            {
                UpdateUI();
            }
        }

        void RemoveHost(string hostName)
        {
            DialogResult dr = MessageBox.Show(String.Format("Are you sure you want to remove \"{0}\"?\r\rAll Guests associated with this Host will also be removed.", hostName), "Confirm Host Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

            if (dr == DialogResult.Yes)
            {
                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);

                foreach (string guest in guiXmlWrapper.GetGuestsFromHost(hostName))
                {
                    guiXmlWrapper.RemoveGuest(guest, hostName);
                }

                guiXmlWrapper.RemoveHost(hostName);
                guiXmlWrapper.SaveXml();
                UpdateUI();
            }
        }

        void AddHost()
        {
            Host ah = new Host(null, vmrunGUIXmlPath, vmrunPathTextBox.Text);

            if (ah.ShowDialog() == DialogResult.OK)
            {
                UpdateUI();
            }
        }

        void EditGuest(string vmxPath, string hostName)
        {
            Guest ag = new Guest(vmxPath, hostName, vmrunGUIXmlPath, vmrunPathTextBox.Text);

            if (ag.ShowDialog() == DialogResult.OK)
            {
                UpdateUI();
            }
        }

        void RemoveGuest(string vmxPath, string hostName)
        {
            vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
            guiXmlWrapper.RemoveGuest(vmxPath, hostName);
            guiXmlWrapper.SaveXml();
            UpdateUI();
        }

        void AddGuest(string host)
        {
            if (managedHostListView.Items.Count > 0)
            {
                Guest ag = new Guest(null, host, vmrunGUIXmlPath, vmrunPathTextBox.Text);

                if (ag.ShowDialog() == DialogResult.OK)
                {
                    UpdateUI();
                }
            }
            else
            {
                MessageBox.Show("You must specify at least one managed Host before you can add a Guest.", "Missing Host", MessageBoxButtons.OK, MessageBoxIcon.Error);
                managedObjectTabControl.SelectedIndex = 0;
            }
        }

        void vmrunBrowseButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.CheckFileExists = true;
            ofd.CheckPathExists = true;
            ofd.DefaultExt = "exe";
            ofd.Filter = "vmrun.exe|vmrun.exe";
            ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
            ofd.Multiselect = false;

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                vmrunPathTextBox.Text = ofd.FileName;
                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                guiXmlWrapper.SetvmrunPath(ofd.FileName);
                guiXmlWrapper.SaveXml();
            }
        }

        void closeButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        void vmrunGUI_Load(object sender, EventArgs e)
        {
            vmrunGUIXmlPath = vmrunGUIXmlName;
            //vmrunGUIXmlPath = Path.Combine(vmrunGUIXmlDirectory, vmrunGUIXmlName);

            //if (!Directory.Exists(vmrunGUIXmlDirectory))
            //{
            //    Directory.CreateDirectory(vmrunGUIXmlDirectory);
            //}

            UpdateUI();
            guestColumnSorter.SortColumn = 0;
            guestColumnSorter.Order = SortOrder.Ascending;
            guestListView.Sort();
            updateGuestStatusThread = new Thread(UpdateGuestStatus);
            updateGuestStatusThread.Start();

            if (managedHostListView.Items.Count == 0)
            {
                DialogResult dr = MessageBox.Show("You don't currently have any VMware Hosts configured.\r\rWould you like to add one now?", "Add VMware Host", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (dr == DialogResult.Yes)
                {
                    AddHost();
                }
            }
        }

        void UpdateUI()
        {
            vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
            guestListView.Items.Clear();
            managedHostListView.Items.Clear();
            editHostButton.Enabled = false;
            removeHostButton.Enabled = false;
            managedGuestListView.Items.Clear();
            editGuestButton.Enabled = false;
            removeGuestButton.Enabled = false;
            managedCredentialsListView.Items.Clear();
            editCredentialsButton.Enabled = false;
            removeCredentialsButton.Enabled = false;
            vmrunPathTextBox.Text = guiXmlWrapper.GetvmrunPath();

            if ((vmrunPathTextBox.Text == null) || (vmrunPathTextBox.Text.Trim().Length == 0) || (!File.Exists(vmrunPathTextBox.Text)))
            {
                string vmrunPath = null;
                vixInfoWrapper vixInfoWrapper = new vixInfoWrapper();

                if (vixInfoWrapper.DeterminevmrunPath(ref vmrunPath, true))
                {
                    vmrunPathTextBox.Text = vmrunPath;
                    guiXmlWrapper.SetvmrunPath(vmrunPath);
                    guiXmlWrapper.SaveXml();
                }
            }

            foreach (string host in guiXmlWrapper.GetHostNames())
            {
                ListViewItem hostLVI = new ListViewItem(host);
                hostLVI.SubItems.Add(new vmrunInfoXmlWrapper().ConvertTypeToFriendlyName(guiXmlWrapper.GetHostType(host)));
                managedHostListView.Items.Add(hostLVI);

                foreach (string guest in guiXmlWrapper.GetGuestsFromHost(host))
                {
                    ListViewItem guestLVI1 = new ListViewItem(guiXmlWrapper.GetGuestChildNodeInnerText(guest, host, "name"));
                    guestLVI1.Tag = guest;
                    guestLVI1.SubItems.Add(guiXmlWrapper.GetGuestChildNodeInnerText(guest, host, "description"));
                    guestLVI1.SubItems.Add(host);
                    guestLVI1.Tag = guest;
                    guestListView.Items.Add(guestLVI1);
                    ListViewItem guestLVI2 = new ListViewItem(guiXmlWrapper.GetGuestChildNodeInnerText(guest, host, "name"));
                    guestLVI2.SubItems.Add(host);
                    guestLVI2.Tag = guest;
                    managedGuestListView.Items.Add(guestLVI2);
                }
            }

            foreach (string credentials in guiXmlWrapper.GetCredentialsNames())
            {
                ListViewItem credLVI = new ListViewItem(credentials);
                string username = null;
                string password = null;
                guiXmlWrapper.GetCredentials(credentials, out username, out password);
                credLVI.SubItems.Add(username);
                managedCredentialsListView.Items.Add(credLVI);
            }

            nextUpdateGuestStatusTime = DateTime.Now;
        }

        void WriteToRichTextBox(ref RichTextBox rtb, string text, Color colour, bool bold)
        {
            if (InvokeRequired)
            {
                Invoke(new WriteToRichTextBoxDelegate(WriteToRichTextBox), new object[] { rtb, text, colour, bold });
            }
            else
            {
                int selectionStart = rtb.Text.Length;
                rtb.AppendText(String.Format("{0}\r", text));
                rtb.SelectionStart = selectionStart;
                rtb.SelectionLength = (rtb.Text.Length - selectionStart);
                rtb.SelectionColor = colour;

                if (bold)
                {
                    rtb.SelectionFont = new Font(rtb.Font, FontStyle.Bold);
                }

                rtb.SelectionStart = rtb.Text.Length;
                rtb.SelectionLength = 0;
                rtb.Focus();
                rtb.ScrollToCaret();
            }
        }

        string GetComboBoxTextProperty(ref ComboBox cb)
        {
            if (InvokeRequired)
            {
                return Convert.ToString(Invoke(new GetComboBoxTextPropertyDelegate(GetComboBoxTextProperty), new object[] { cb }));
            }
            else
            {
                return cb.Text;
            }
        }

        int GetComboBoxSelectedIndex(ref ComboBox cb)
        {
            if (InvokeRequired)
            {
                return (int)Invoke(new GetComboBoxSelectedIndexDelegate(GetComboBoxSelectedIndex), new object[] { cb });
            }
            else
            {
                return cb.SelectedIndex;
            }
        }

        vmrunGUIXmlWrapper.VMwareGuest[] GetSelectedGuests(ref ListView lv)
        {
            if (InvokeRequired)
            {
                return (vmrunGUIXmlWrapper.VMwareGuest[])Invoke(new GetSelectedGuestsDelegate(GetSelectedGuests), new object[] { lv });
            }
            else
            {
                ArrayList guests = new ArrayList();

                foreach (ListViewItem lvi in lv.CheckedItems)
                {
                    vmrunGUIXmlWrapper.VMwareGuest guest = new vmrunGUIXmlWrapper.VMwareGuest();
                    guest.vmxPath = lvi.Tag.ToString();
                    guest.host = lvi.SubItems[2].Text;
                    guests.Add(guest);
                }

                return (vmrunGUIXmlWrapper.VMwareGuest[])guests.ToArray(typeof(vmrunGUIXmlWrapper.VMwareGuest));
            }
        }

        vmrunGUIXmlWrapper.VMwareGuest[] GetGuests(ref ListView lv)
        {
            if (InvokeRequired)
            {
                return (vmrunGUIXmlWrapper.VMwareGuest[])Invoke(new GetGuestsDelegate(GetGuests), new object[] { lv });
            }
            else
            {
                ArrayList guests = new ArrayList();

                foreach (ListViewItem lvi in lv.Items)
                {
                    vmrunGUIXmlWrapper.VMwareGuest guest = new vmrunGUIXmlWrapper.VMwareGuest();
                    guest.vmxPath = lvi.Tag.ToString();
                    guest.host = lvi.SubItems[2].Text;
                    guests.Add(guest);
                }

                return (vmrunGUIXmlWrapper.VMwareGuest[])guests.ToArray(typeof(vmrunGUIXmlWrapper.VMwareGuest));
            }
        }

        string GetTextBoxTextProperty(ref TextBox tb)
        {
            if (InvokeRequired)
            {
                return Convert.ToString(Invoke(new GetTextBoxTextPropertyDelegate(GetTextBoxTextProperty), new object[] { tb }));
            }
            else
            {
                return tb.Text;
            }
        }

        void SetButtonEnableProperty(ref Button b, bool enabled)
        {
            if (InvokeRequired)
            {
                Invoke(new SetButtonEnablePropertyDelegate(SetButtonEnableProperty), new object[] { b, enabled });
            }
            else
            {
                b.Enabled = enabled;
            }
        }

        void SetTabPageEnableState(ref TabPage tp, bool enabled)
        {
            if (InvokeRequired)
            {
                Invoke(new SetTabPageEnableStateDelegate(SetTabPageEnableState), new object[] { tp, enabled });
            }
            else
            {
                foreach (Control c in tp.Controls)
                {
                    if (enabled)
                    {
                        c.Enabled = Convert.ToBoolean(c.Tag);
                    }
                    else
                    {
                        c.Tag = c.Enabled;
                        c.Enabled = false;
                    }
                }
            }
        }

        void SetTabControlSelectedIndex(ref TabControl tc, int index)
        {
            if (InvokeRequired)
            {
                Invoke(new SetTabControlSelectedIndexDelegate(SetTabControlSelectedIndex), new object[] { tc, index });
            }
            else
            {
                tc.SelectedIndex = index;
            }
        }

        void UpdateGuestStatus()
        {
            while (true)
            {
                while (DateTime.Now < nextUpdateGuestStatusTime)
                {
                    Thread.Sleep(250);
                }

                if ((guestListView.Items.Count > 0) && ((executeCommandThread == null) || (executeCommandThread.ThreadState == System.Threading.ThreadState.Stopped)))
                {
                    vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(vmrunGUIXmlPath);
                    ArrayList hostsInUse = new ArrayList();

                    foreach (vmrunGUIXmlWrapper.VMwareGuest guest in GetGuests(ref guestListView))
                    {
                        if (!hostsInUse.Contains(guest.host))
                        {
                            hostsInUse.Add(guest.host);
                        }
                    }

                    hostsInUse.Sort();

                    foreach (string host in hostsInUse)
                    {
                        ArrayList guests = new ArrayList();
                        string username = null;
                        string password = null;
                        int exitCode;
                        ArrayList listGuests;
                        guiXmlWrapper.GetCredentials(guiXmlWrapper.GetHostChildNodeInnerText(host, "credentials"), out username, out password);
                        vmrunCLIWrapper cliWrapper = new vmrunCLIWrapper(vmrunPathTextBox.Text, guiXmlWrapper.GetHostType(host), guiXmlWrapper.GetHostChildNodeInnerText(host, "arguments"), username, password, null, null, "list");
                        cliWrapper.ExecuteCommand(vmrunProcessTimeoutSeconds, out listGuests, out exitCode);

                        foreach (string guest in guiXmlWrapper.GetGuestsFromHost(host))
                        {
                            vmrunGUIXmlWrapper.VMwareGuest vmGuest = new vmrunGUIXmlWrapper.VMwareGuest();
                            vmGuest.host = host;
                            vmGuest.vmxPath = guest;

                            if (exitCode == 0)
                            {
                                if (listGuests.Contains(guest))
                                {
                                    vmGuest.status = vmrunGUIXmlWrapper.GuestStatus.PoweredOn;
                                }
                                else
                                {
                                    vmGuest.status = vmrunGUIXmlWrapper.GuestStatus.PoweredOff;
                                }
                            }
                            else
                            {
                                vmGuest.status = vmrunGUIXmlWrapper.GuestStatus.Unknown;
                            }

                            guests.Add(vmGuest);
                        }

                        UpdateGuestStateImages((vmrunGUIXmlWrapper.VMwareGuest[])guests.ToArray(typeof(vmrunGUIXmlWrapper.VMwareGuest)));
                    }
                }

                nextUpdateGuestStatusTime = DateTime.Now.AddSeconds(guestStateUpdateIntervalSeconds);
            }
        }

        void UpdateGuestStateImages(vmrunGUIXmlWrapper.VMwareGuest[] guests)
        {
            try
            {
                if (InvokeRequired)
                {
                    Invoke(new UpdateGuestStateImagesDelegate(UpdateGuestStateImages), new object[] { guests });
                }
                else
                {
                    if ((guests != null) && (guests.Length > 0))
                    {
                        foreach (ListViewItem lvi in guestListView.Items)
                        {
                            foreach (vmrunGUIXmlWrapper.VMwareGuest guest in guests)
                            {
                                try
                                {
                                    if ((guest.vmxPath.Equals(lvi.Tag.ToString())) && (guest.host.Equals(lvi.SubItems[2].Text)))
                                    {
                                        int imageIndex;

                                        switch (guest.status)
                                        {
                                            case vmrunGUIXmlWrapper.GuestStatus.PoweredOn:
                                                imageIndex = guestOnImageIndex;
                                                break;
                                            case vmrunGUIXmlWrapper.GuestStatus.PoweredOff:
                                                imageIndex = guestOffImageIndex;
                                                break;
                                            case vmrunGUIXmlWrapper.GuestStatus.Unknown:
                                                imageIndex = guestWarningIconIndex;
                                                break;
                                            default:
                                                imageIndex = guestWarningIconIndex;
                                                break;
                                        }

                                        if (lvi.ImageIndex != imageIndex)
                                        {
                                            lvi.ImageIndex = imageIndex;
                                        }

                                        break;
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
            }
        }

        string ConvertToBatchPasswordVariable(string text)
        {
            string variableName = text;
            variableName = variableName.Replace(Convert.ToChar(" "), Convert.ToChar("_"));
            variableName = String.Format("{0}_Password", variableName);
            return variableName.ToUpper().Trim();
        }
    }
}
